package com.ufgov.ip.web;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springside.modules.security.utils.Digests;
import org.springside.modules.utils.Encodes;

import uap.web.auth.Constants;
import uap.web.httpsession.cache.SessionCacheManager;
import uap.web.utils.RSAUtils;
import uap.web.utils.TokenGenerator;

import com.ufgov.ip.entity.IpHirer;
import com.ufgov.ip.entity.IpUser;
import com.ufgov.ip.service.HirerAccountService;
import com.ufgov.ip.service.MenuService;
import com.ufgov.ip.service.UserAccountService;
import com.ufgov.ip.util.MD5;

/**
 * LoginController负责打开登录页面(GET请求)和登录出错页面(POST请求)，
 * 
 * 真正登录的POST请求由Filter完成,
 */
@Controller
@RequestMapping(value = "/login")
public class UserLoginController {
	
    private final Logger logger = LoggerFactory.getLogger(getClass());
	
	public static final int HASH_INTERATIONS = 1024;
	// 默认一天
	public static final int COOKIES_MAXAGE = 60 * 60 * 24;
	private static final int SALT_SIZE = 8;
	
    @Autowired
    private SessionCacheManager sessionCacheManager;

	@Autowired
	protected UserAccountService userAccountService;
	
	@Autowired
	protected HirerAccountService hirerAccountService;
	
	//菜单
	@Autowired
	private MenuService menuService;

	public void setMenuService(MenuService menuService) {
		this.menuService = menuService;
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public String userlogin(Model model) {
		initPubKeyParams(model);
		return "login";
	}
	
	public void initPubKeyParams(Model model) {
		RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey();
    	String publicKeyExponent = publicKey.getPublicExponent().toString(16);//16进制
 	    String publicKeyModulus = publicKey.getModulus().toString(16);//16进制
 	    model.addAttribute("exponent", publicKeyExponent);
 	    model.addAttribute("modulus", publicKeyModulus);
	}
	
	@RequestMapping(method = RequestMethod.POST,value="uformLogin")
	public String uformLogin(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException {
        String userName = request.getParameter("username");
        String encryptedPassWord = request.getParameter("password");
        encryptedPassWord = encryptedPassWord.replace("_encrypted", "");
        String passWord = RSAUtils.decryptStringByJs(encryptedPassWord);
        
//        //将用户名存放在cookie里面
//        Cookie nameCookie=new Cookie("username",userName);
//        //浏览器关闭时候删除cookie
//        nameCookie.setMaxAge(-1);
//        nameCookie.setHttpOnly(true);
//        response.addCookie(nameCookie);
        
        
        String imageCode = request.getParameter("imageCode");
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
        	String cookieName = cookie.getName();
        	if("piccode".equals(cookieName)){
        		String value = cookie.getValue();
        		if(!value.equalsIgnoreCase(imageCode)){
        			model.addAttribute("accounterror", "你输入的验证码不正确!");
        			initPubKeyParams(model);
        			return "login";
        		}
        	}
		}
        /**
         * 获得运维人员属性文件
         */
        Properties pro=new Properties();
        ClassPathResource classPathResource = new ClassPathResource("operation.properties");
        InputStream inputStream = classPathResource.getInputStream();
        pro.load(inputStream);
        
        /**
         * 判断是否为普通用户、租户、运维管理员 
         * 都是相互独立的
         * 
         */
        
        IpUser ipUser=userAccountService.findUserByUserEmailOrLoginNameOrCellphoneNo(userName); //普通用户
        IpHirer ipHirer = hirerAccountService.findHirerByEmailOrLoginNameOrCellphoneNo(userName);//租户
        
        String op_name = pro.getProperty("username");//运维人员用户名
        String op_password=pro.getProperty("password");//运维人员用户名密码

        String path=new String();
        if(encryptedPassWord!=null){
        	
        	if(ipUser != null && Encodes.encodeHex(Digests.sha1(passWord.getBytes(), Encodes.decodeHex(ipUser.getSalt()), HASH_INTERATIONS)).equals(ipUser.getPassword())){
        		long ts = System.currentTimeMillis();
        		// 判断该用户已停用 
        		if("0".equals(ipUser.getIsEnabled())){
        			model.addAttribute("accounterror", "该用户已停用，请确认!");
        	        initPubKeyParams(model);
        	        return "login";
        		}
        		ipUser.setLoginTs(ts);
        		path=checkLogin(userName, response,ts);
        		//把登陆信息写入到redis缓存中
                try {
                    sessionCacheManager.cacheUser(userName, ipUser);
                } catch (Exception e) {
                    logger.error("登陆信息写入到redis缓存中失败!", e);
                }
                
                model.addAttribute("usertype", "user");
                model.addAttribute("hirerId", ipUser.getHirerId());
        		
        	}else {
                
        		if(ipHirer!=null && Encodes.encodeHex(Digests.sha1(passWord.getBytes(), Encodes.decodeHex(ipHirer.getSalt()), HASH_INTERATIONS)).equals(ipHirer.getPassword())){
        			long ts = System.currentTimeMillis();
        			ipHirer.setLoginTs(ts);
        			path=checkLogin(userName, response,ts);
        			
            		//把登陆信息写入到redis缓存中
                    try {
                        sessionCacheManager.cacheUser(userName, ipHirer);
                    } catch (Exception e) {
                        logger.error("登陆信息写入到redis缓存中失败!", e);
                    }
                    model.addAttribute("usertype", "hirer");
                    model.addAttribute("hirerId", ipHirer.getHirerId());
        		}else{
        			
        			if(op_name!=null && (new MD5().GetMD5Code(passWord)).equals(op_password)){
        				long ts = System.currentTimeMillis();
        				pro.setProperty("ts", String.valueOf(ts));
        				path=checkLogin(userName, response,ts);
        				inputStream.close();
                		//把登陆信息写入到redis缓存中
                        try {
                            sessionCacheManager.cacheUser(userName, pro);
                        } catch (Exception e) {
                            logger.error("登陆信息写入到redis缓存中失败!", e);
                        }
        				
        			}else{
        				model.addAttribute("accounterror", "用户名与密码不匹配，请重新输入!");
        				initPubKeyParams(model);
                        return "login";
        			}
        		}
            }
        	//获得所有的一级菜单
        	//List<IpMenu> menuList = menuService.findAllFirstLevel(new String[]{"1"});
        	//model.addAttribute("menuList", menuList);
        	return path;	
        }else {
            model.addAttribute("accounterror", "你输入的用户不存在!");
            initPubKeyParams(model);
            return "login";
		}
	}
	
	@RequestMapping(method = RequestMethod.POST)
	public String fail(@RequestParam(FormAuthenticationFilter.DEFAULT_USERNAME_PARAM) String userName, Model model) {
		model.addAttribute(FormAuthenticationFilter.DEFAULT_USERNAME_PARAM, userName);
		initPubKeyParams(model);
		return "login";
	}
	
	public String checkLogin(String userName, HttpServletResponse response,long ts){
			
               // long ts = System.currentTimeMillis();
                String cookieValue = "";
                try {
                    cookieValue = TokenGenerator.genToken(userName, ts, sessionCacheManager.findSeed());
                } catch (Throwable e) {
                    logger.error("Fail to generate cookie!", e);
                }

                // 校验成功，写cookie
                HashMap<String, String> cookiesMap = new HashMap<String, String>();
                cookiesMap.put(Constants.PARAM_USERNAME, userName);
                cookiesMap.put(Constants.PARAM_TOKEN, cookieValue);
                for (Iterator<String> iterator = cookiesMap.keySet().iterator(); iterator.hasNext(); ) {
                    String key = iterator.next();
                    Cookie cookie = new Cookie(key, URLEncoder.encode(cookiesMap.get(key)));
                    cookie.setPath(Constants.COOKIES_PATH);
                    //浏览器关闭时候删除cookie
                   //  cookie.setMaxAge(-1);
                    cookie.setMaxAge(-1);
                    cookie.setHttpOnly(true);
                    response.addCookie(cookie);
                }
           
            return "redirect";
	    }
	public HirerAccountService getHirerAccountService() {
		return hirerAccountService;
	}

	public void setHirerAccountService(HirerAccountService hirerAccountService) {
		this.hirerAccountService = hirerAccountService;
	}

	//验证码的生成
	@RequestMapping(value="/getImage")
	public void getImage(HttpServletRequest request, HttpServletResponse response) throws Exception{
		 System.out.println("#######################生成数字和字母的验证码######(68,22),(15,3,18)#################");  
	        BufferedImage img = new BufferedImage(109,49,  
	  
	        BufferedImage.TYPE_INT_RGB);  
	  
	        // 得到该图片的绘图对象    
	  
	        Graphics g = img.getGraphics();  
	  
	        Random r = new Random();  
	  
	        Color c = new Color(200, 150, 255);  
	  
	        g.setColor(c);  
	  
	        // 填充整个图片的颜色    
	  
	        g.fillRect(0, 0, 109, 49);  
	  
	        // 向图片中输出数字和字母    
	  
	        StringBuffer sb = new StringBuffer();  
	  
	        char[] ch = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789".toCharArray();  
	  
	        int index, len = ch.length;  
	  
	        for (int i = 0; i < 4; i++) {  
	  
	            index = r.nextInt(len);  
	  
	            g.setColor(new Color(r.nextInt(88), r.nextInt(188), r.nextInt  
	  
	            (255)));  
	  
	            g.setFont(new Font("Arial", Font.BOLD | Font.ITALIC, 22));  
	            // 输出的  字体和大小                      
	  
	            g.drawString("" + ch[index], (i * 22) + 6, 29);  
	            //写什么数字，在图片 的什么位置画    
	  
	            sb.append(ch[index]);  
	  
	        }  
	        //把验证码的值放入session中以便于验证
	        //request.getSession().setAttribute("piccode", sb.toString()); 
	        //sessionCacheManager.cacheUser("piccode", sb.toString());
	        //request.setAttribute("piccode", sb.toString());
	        Cookie cookie=new Cookie("piccode", sb.toString());
	        cookie.setPath(Constants.COOKIES_PATH);
            //浏览器关闭时候删除cookie
            cookie.setMaxAge(-1);
            cookie.setHttpOnly(true);
            response.addCookie(cookie);
	        
	        ImageIO.write(img, "JPG", response.getOutputStream());  
	}
	
	
	//用户登出
//	@RequestMapping(method = RequestMethod.GET,value="userLogout")
//	public String logout(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException {
//		/*Subject currentUser = SecurityUtils.getSubject();//获得Subject
//		Session session = currentUser.getSession();
//		session.removeAttribute("userName");*/
//		SecurityUtils.getSubject().logout();
//		initPubKeyParams(model);
//		return "login";
//	}
	
	
	
	
	
    //校验验证码
	@RequestMapping(method = RequestMethod.POST,value="/checkImage")
	public void checkImage(HttpServletRequest request, HttpServletResponse response) throws Exception{
		String imageCode = request.getParameter("imageCode");
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
        	String cookieName = cookie.getName();
        	if("piccode".equals(cookieName)){//修复验证码区分大小写 equalsIgnoreCase
        		String value = cookie.getValue();
        		if(!value.equalsIgnoreCase(imageCode)){
        			response.getWriter().write("false");
        		}else{
        			response.getWriter().write("true");
        		}
        	}
		}
	}
	
	public Boolean checkImageCode(HttpServletRequest request, Model model) {
		String imageCode = request.getParameter("imageCode");
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
        	String cookieName = cookie.getName();
        	if("piccode".equals(cookieName)){
        		String value = cookie.getValue();
        		if(!value.equalsIgnoreCase(imageCode)){
        			model.addAttribute("accounterror", "你输入的验证码不正确!");
        			initPubKeyParams(model);
        			return false;
        		}
        	}
		}
		return true;
	}
	
	
	
	private void entryptPassword(IpHirer hirer) {
		byte[] salt = Digests.generateSalt(SALT_SIZE);
		hirer.setSalt(Encodes.encodeHex(salt));
		byte[] hashPassword = Digests.sha1(hirer.getPassword().getBytes(), salt, HASH_INTERATIONS);
		hirer.setPassword(Encodes.encodeHex(hashPassword));
	}

}
